﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MongoDB.Bson.Serialization;
using Moq;

namespace Yamfinder.Data.Tests
{
    [TestClass]
    public class LexicalEntryIntegrationTests
    {
        private IDataSource _dataSource;
        private ILexicalRepository _lexicalRepository ;
        private Mock<IDataDictonaryRepository> _dataDicMock;

        [TestInitialize]
        public void Init()
        {
            _dataSource = new DataSource();
            _lexicalRepository = new LexicalRepository(_dataSource);
            _dataDicMock = new Mock<IDataDictonaryRepository>();

            BsonSerializer.RegisterSerializer(typeof(LexicalEntry),new LexicalEntrySerialiser(_dataDicMock.Object));
        }

        [TestMethod]
        public void TestInsertAndRemoveAndQueryAndSaveAndGet()
        {
            var lexicalEntry = new LexicalEntry()
                                   {
                                       Fields =
                                           new Dictionary<string, object>()
                                               {
                                                   {"Field1", "TestValue"},
                                                   {"Field2", 12},
                                                   {"Field3", 99.4},
                                                   {"Field4", "Kablam!"},
                                                   {"DateTest", DateTime.Now},
                                                   {"GPSTest", new GPSLoc() {Lat = 134.34343, Lon = -122.33345}}
                                               }
                                   };

            _dataDicMock.Setup(x => x.Get("Field1")).Returns(new DataDictonaryEntry() {Type = "Text"});
            _dataDicMock.Setup(x => x.Get("Field2")).Returns(new DataDictonaryEntry() { Type = "Integer" });
            _dataDicMock.Setup(x => x.Get("Field3")).Returns(new DataDictonaryEntry() { Type = "Decimal" });
            _dataDicMock.Setup(x => x.Get("Field4")).Returns(new DataDictonaryEntry() { Type = "RelativeFileLoc" });
            _dataDicMock.Setup(x => x.Get("DateTest")).Returns(new DataDictonaryEntry() { Type = "Date" });
            _dataDicMock.Setup(x => x.Get("GPSTest")).Returns(new DataDictonaryEntry() { Type = "GPSLocation" });
            _dataDicMock.Setup(x => x.Get("FieldX")).Returns(new DataDictonaryEntry() { Type = "Text" });

            _lexicalRepository.Insert(lexicalEntry);

            var results = _lexicalRepository.Query(MongoDB.Driver.Builders.Query.EQ("Field4", "Kablam!"));
            Assert.IsTrue(results.Count > 0);

            lexicalEntry = results[0];

            Assert.IsTrue(((GPSLoc)lexicalEntry.Fields["GPSTest"]).Lat == 134.34343);

            lexicalEntry.Fields.Add("FieldX","TestSaveValue");
            var gpsLoc = (GPSLoc)lexicalEntry.Fields["GPSTest"];
            gpsLoc.Lat = 10;
            lexicalEntry.Fields["GPSTest"] = gpsLoc;

            _lexicalRepository.Save(lexicalEntry);

            var newLexical = _lexicalRepository.Get(lexicalEntry.Id);

            Assert.AreEqual(newLexical.Fields["FieldX"], "TestSaveValue");
            Assert.AreEqual(((GPSLoc) newLexical.Fields["GPSTest"]).Lat, 10);

            foreach (var result in results)
            {
                _lexicalRepository.Remove(result.Id);
            }

            results = _lexicalRepository.Query(MongoDB.Driver.Builders.Query.EQ("Field4", "Kablam!"));
            Assert.IsTrue(results.Count == 0);
        }
    }
}
